package com.dbb.trade.util;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 13-1-28
 * Time: 下午2:11
 * To change this template use File | Settings | File Templates.
 */
public class TreeNode {
    public final static char CHAR_SPLITE = (char)92;
    private String id;
    private TreeNode parent;
    private List<TreeNode> children;
    private NodeData data;

    public TreeNode(String id, TreeNode parent, List<TreeNode> children,
                    NodeData data) {
        super();
        this.id = id;
        this.parent = parent;
        this.children = children;
        this.data = data;
    }

    public TreeNode(String path) {
        if(path.indexOf(CHAR_SPLITE) != -1) {
            children = new ArrayList<TreeNode>();
            id = path.substring(0, path.indexOf(CHAR_SPLITE));
            children.add(new TreeNode(path.substring(path.indexOf(CHAR_SPLITE) + 1)));
        } else {
            id = path;
        }
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public TreeNode getParent() {
        return parent;
    }

    public void setParent(TreeNode parent) {
        this.parent = parent;
    }

    public List<TreeNode> getChildren() {
        return children;
    }

    public void setChildren(List<TreeNode> children) {
        this.children = children;
    }

    public NodeData getData() {
        return data;
    }

    public void setData(NodeData data) {
        this.data = data;
    }

    /**
     * 当前节点是否是根节点
     *
     * @return
     */
    public boolean isRoot() {
        return this.parent == null;
    }

    /**
     * 当前节点是否是叶子节点
     *
     * @return
     */
    public boolean isLeaf() {
        return (this.children != null && this.children.size() > 0) ;
    }

    /**
     * 对该节点及其子树进行层次遍历
     *
     * @param treeNode
     */
    public static void levelTraversal(TreeNode treeNode) {
        if (treeNode == null) {
            return;
        }
        if (treeNode.isLeaf()) {
            treeNode.data.output();
        } else {
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            queue.offer(treeNode);
            while (queue.size() > 0) {
                TreeNode node = queue.poll();
                node.data.output();

                if (!node.isLeaf()) {
                    for (int i = 0; i < node.children.size(); i++) {
                        queue.offer(node.children.get(i));
                    }
                }
            }
        }
    }

    /**
     * 查找特点的节点，在此使用层次遍历进行查找
     *
     * @param id
     * @param treeNode
     * @return
     */
    public static TreeNode search(String id, TreeNode treeNode) {
        if (treeNode == null) {
            return null;
        }
        if (treeNode.isLeaf()) {
            if (id.equals(treeNode.id)) {
                return treeNode;
            } else {
                return null;
            }
        } else {
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            queue.offer(treeNode);
            while (queue.size() > 0) {
                TreeNode node = queue.poll();
                if (node.id == id) {
                    return node;
                }

                if (!node.isLeaf()) {
                    for (int i = 0; i < node.children.size(); i++) {
                        queue.offer(node.children.get(i));
                    }
                }
            }

            return null;
        }
    }

    /**
     * 将节点插入为另一个节点的孩子
     *
     * @param childNode
     * @param toBeAppended
     * @return
     */
    public static boolean appendAsChild(TreeNode childNode,
                                        TreeNode toBeAppended) {
        if (childNode == null || toBeAppended == null) {
            return false;
        } else {
            if (toBeAppended.isLeaf()) {
                List<TreeNode> children = new ArrayList<TreeNode>();
                children.add(childNode);
                toBeAppended.children = children;
            } else {
                toBeAppended.children.add(childNode);
            }

            return true;
        }
    }

    /**
     * 将节点插入为另一个节点的兄弟
     *
     * @param sublingNode
     * @param toBeAppended
     * @return
     */
    public static boolean appendAsSubling(TreeNode sublingNode,
                                          TreeNode toBeAppended) {
        if (sublingNode == null || toBeAppended == null) {
            return false;
        } else {
            // 单根树，无法对根节点添加兄弟
            if (toBeAppended.isRoot()) {
                return false;
            } else {
                toBeAppended.parent.children.add(sublingNode);
                return true;
            }
        }
    }

    public TreeNode containId(String nodeId) {
        for(TreeNode tn : this.children) {
            if(nodeId.equals(tn.getId())){
                return tn;
            }
        }
        return null;
    }
    
    public TreeNode addChildren(List<TreeNode> nodes) {
        for(TreeNode node : nodes) {
            if(this.children != null) {
                TreeNode child = containId(node.getId());
                if(child != null) {
                    if(node.getChildren() != null) {
                        child.addChildren(node.getChildren());
                    }
                } else {
                    this.children.add(node);
                }
            } else {
                List<TreeNode> ns = new ArrayList<TreeNode>();
                ns.add(node);
                this.children = ns;
            }

        }
        return this;
    }
    
    public String toTree() {
        StringBuffer sb = new StringBuffer();
        sb.append("<ul class=\"jqueryFileTree\" style=\"display: none;\">");
        for(TreeNode tn : this.children) {
            if(tn.getChildren() != null) {
                sb.append("<li class=\"directory collapsed\"><a href=\"#\" rel=\"" + tn.getId() + "\" >" + tn.getId() + "</a></li>");
            }
        }
        for(TreeNode tn : this.children) {
            if(tn.getChildren() == null) {
                int dotIndex = tn.getId().lastIndexOf('.');
                String ext = dotIndex > 0 ? tn.getId().substring(dotIndex + 1) : "";
                sb.append("<li class=\"file ext_" + ext + "\"><a href=\"#\" rel=\"" + tn.getId() + "\">" + tn.getId() + "</a></li>");
            }
        }
        sb.append("</ul>");
        return sb.toString();
    }
}
